<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-4xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">音频输出设备 API</h1>
        <p class="text-gray-300 text-lg">
          选择和控制音频输出设备，支持多设备切换和音量控制
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300 mb-4">
          您的浏览器不支持 Audio Output Devices API。此功能需要 Chrome 88+ 或其他支持的浏览器。
        </p>
        <p class="text-gray-400 text-sm">
          注意：此 API 需要在安全上下文（HTTPS）中使用。
        </p>
      </div>

      <!-- 音频播放器 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">音频播放器</h2>
        
        <div class="bg-gray-800 rounded-lg p-6 mb-6">
          <audio
            ref="audioElement"
            controls
            class="w-full mb-4"
            @loadedmetadata="onAudioLoaded"
          >
            <source src="https://www.soundjay.com/misc/sounds/bell-ringing-05.wav" type="audio/wav">
            您的浏览器不支持音频播放
          </audio>
          
          <div class="flex flex-wrap gap-4 mb-4">
            <button
              @click="playTestTone"
              class="tech-button"
            >
              <i class="i-carbon-play mr-2"></i>
              播放测试音调
            </button>
            
            <button
              @click="stopAudio"
              class="bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors"
            >
              <i class="i-carbon-stop mr-2"></i>
              停止播放
            </button>
          </div>

          <!-- 音量控制 -->
          <div class="mb-4">
            <label class="block text-gray-300 mb-2">音量控制:</label>
            <div class="flex items-center gap-4">
              <i class="i-carbon-volume-down text-gray-400"></i>
              <input
                v-model="volume"
                type="range"
                min="0"
                max="100"
                @input="updateVolume"
                class="flex-1 h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"
              >
              <i class="i-carbon-volume-up text-gray-400"></i>
              <span class="text-white text-sm w-12">{{ volume }}%</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 输出设备选择 -->
      <div v-if="isSupported" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">音频输出设备</h3>
        
        <div class="mb-6">
          <button
            @click="enumerateDevices"
            class="tech-button"
          >
            <i class="i-carbon-search mr-2"></i>
            扫描音频设备
          </button>
        </div>

        <!-- 设备列表 -->
        <div v-if="audioDevices.length > 0" class="space-y-4">
          <h4 class="text-lg font-semibold text-white">可用的音频输出设备:</h4>
          
          <div class="grid gap-4">
            <div
              v-for="device in audioDevices"
              :key="device.deviceId"
              class="bg-gray-800 rounded-lg p-4 flex items-center justify-between"
            >
              <div class="flex-1">
                <h5 class="text-white font-medium">
                  {{ device.label || `设备 ${device.deviceId.substring(0, 8)}...` }}
                </h5>
                <p class="text-gray-400 text-sm">
                  类型: {{ device.kind }} | 
                  ID: {{ device.deviceId.substring(0, 20) }}...
                </p>
                <p v-if="device.groupId" class="text-gray-400 text-xs">
                  组ID: {{ device.groupId.substring(0, 20) }}...
                </p>
              </div>
              
              <div class="flex items-center gap-3">
                <span
                  v-if="currentDeviceId === device.deviceId"
                  class="text-green-400 text-sm font-medium"
                >
                  当前使用
                </span>
                <button
                  @click="selectOutputDevice(device.deviceId)"
                  :disabled="currentDeviceId === device.deviceId"
                  class="bg-blue-600 hover:bg-blue-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-2 rounded-lg transition-colors text-sm"
                >
                  <i class="i-carbon-audio-console mr-1"></i>
                  选择
                </button>
              </div>
            </div>
          </div>
        </div>

        <div v-else-if="!isLoading" class="text-center text-gray-400 py-8">
          <i class="i-carbon-audio-console text-4xl mb-4 block mx-auto opacity-50"></i>
          <p>暂无可用的音频输出设备</p>
          <p class="text-sm mt-2">点击上方按钮扫描设备</p>
        </div>

        <div v-if="isLoading" class="text-center text-gray-400 py-8">
          <i class="i-carbon-loading text-4xl mb-4 block mx-auto animate-spin"></i>
          <p>正在扫描音频设备...</p>
        </div>
      </div>

      <!-- 设备信息 -->
      <div v-if="currentDevice" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-4 text-white">当前设备信息</h3>
        
        <div class="bg-gray-800 rounded-lg p-6">
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
            <div>
              <span class="text-gray-400">设备名称:</span>
              <span class="text-white ml-2">{{ currentDevice.label || '未知设备' }}</span>
            </div>
            <div>
              <span class="text-gray-400">设备类型:</span>
              <span class="text-white ml-2">{{ currentDevice.kind }}</span>
            </div>
            <div>
              <span class="text-gray-400">设备ID:</span>
              <span class="text-white ml-2 font-mono text-xs">{{ currentDevice.deviceId }}</span>
            </div>
            <div v-if="currentDevice.groupId">
              <span class="text-gray-400">组ID:</span>
              <span class="text-white ml-2 font-mono text-xs">{{ currentDevice.groupId }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 错误信息 -->
      <div v-if="error" class="tech-card border-red-600 mb-8">
        <div class="flex items-center mb-2">
          <i class="i-carbon-warning text-red-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-red-500">错误</h3>
        </div>
        <p class="text-gray-300">{{ error }}</p>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>Chrome 88+, Edge 88+ (需要启用实验性功能)</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要方法</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">navigator.mediaDevices.enumerateDevices()</code> - 枚举设备</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">audio.setSinkId(deviceId)</code> - 设置输出设备</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">audio.sinkId</code> - 获取当前输出设备ID</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>多媒体应用的音频输出选择</li>
              <li>会议软件的扬声器切换</li>
              <li>音频编辑软件的监听设备选择</li>
              <li>游戏中的音频设备管理</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">权限要求</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>需要在安全上下文（HTTPS）中使用</li>
              <li>某些浏览器需要用户授权访问媒体设备</li>
              <li>设备标签可能需要麦克风权限才能显示</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, useTemplateRef } from 'vue'

// 响应式状态
const isSupported = ref(false)
const audioDevices = ref<MediaDeviceInfo[]>([])
const currentDeviceId = ref('')
const volume = ref(50)
const isLoading = ref(false)
const error = ref('')

// 音频相关
const audioElement = useTemplateRef<HTMLAudioElement>('audioElement')
let audioContext: AudioContext | null = null
let oscillator: OscillatorNode | null = null

// 计算属性
const currentDevice = computed(() => 
  audioDevices.value.find(device => device.deviceId === currentDeviceId.value)
)

// 初始化
onMounted(() => {
  checkSupport()
  initAudio()
})

// 检查浏览器支持
const checkSupport = () => {
  isSupported.value = !!(
    navigator.mediaDevices && 
    'enumerateDevices' in navigator.mediaDevices &&
    'setSinkId' in HTMLAudioElement.prototype
  )
}

// 初始化音频
const initAudio = () => {
  if (audioElement.value) {
    audioElement.value.volume = volume.value / 100
  }
}

// 音频加载完成
const onAudioLoaded = () => {
  if (audioElement.value) {
    currentDeviceId.value = (audioElement.value as any).sinkId || 'default'
  }
}

// 枚举音频设备
const enumerateDevices = async () => {
  try {
    isLoading.value = true
    error.value = ''
    
    // 请求媒体权限以获取设备标签
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
      stream.getTracks().forEach(track => track.stop())
    } catch (e) {
      console.warn('无法获取麦克风权限，设备标签可能不可用')
    }
    
    const devices = await navigator.mediaDevices.enumerateDevices()
    audioDevices.value = devices.filter(device => device.kind === 'audiooutput')
    
    if (audioDevices.value.length === 0) {
      error.value = '未找到音频输出设备'
    }
  } catch (err) {
    console.error('枚举设备失败:', err)
    error.value = err instanceof Error ? err.message : '枚举设备失败'
  } finally {
    isLoading.value = false
  }
}

// 选择输出设备
const selectOutputDevice = async (deviceId: string) => {
  try {
    error.value = ''
    
    if (audioElement.value && (audioElement.value as any).setSinkId) {
      await (audioElement.value as any).setSinkId(deviceId)
      currentDeviceId.value = deviceId
    } else {
      throw new Error('当前浏览器不支持设置音频输出设备')
    }
  } catch (err) {
    console.error('设置输出设备失败:', err)
    error.value = err instanceof Error ? err.message : '设置输出设备失败'
  }
}

// 播放测试音调
const playTestTone = () => {
  try {
    error.value = ''
    
    // 停止之前的音调
    stopAudio()
    
    // 创建音频上下文
    audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()
    
    // 创建振荡器
    oscillator = audioContext.createOscillator()
    const gainNode = audioContext.createGain()
    
    // 设置音调参数
    oscillator.frequency.setValueAtTime(440, audioContext.currentTime) // A4 音符
    oscillator.type = 'sine'
    
    // 设置音量
    gainNode.gain.setValueAtTime(volume.value / 100 * 0.3, audioContext.currentTime)
    
    // 连接节点
    oscillator.connect(gainNode)
    gainNode.connect(audioContext.destination)
    
    // 播放音调
    oscillator.start()
    
    // 2秒后自动停止
    setTimeout(() => {
      stopAudio()
    }, 2000)
    
  } catch (err) {
    console.error('播放测试音调失败:', err)
    error.value = err instanceof Error ? err.message : '播放测试音调失败'
  }
}

// 停止音频
const stopAudio = () => {
  if (oscillator) {
    try {
      oscillator.stop()
    } catch (e) {
      // 忽略重复停止的错误
    }
    oscillator = null
  }
  
  if (audioContext) {
    audioContext.close()
    audioContext = null
  }
  
  if (audioElement.value) {
    audioElement.value.pause()
    audioElement.value.currentTime = 0
  }
}

// 更新音量
const updateVolume = () => {
  if (audioElement.value) {
    audioElement.value.volume = volume.value / 100
  }
}
</script>
